package by.wind.drebedengi.utils;

import java.util.HashSet;
import java.util.Set;
import java.util.Stack;



public class Convertor {
	
	public static String getDigits(String source) {
		int i = 0;
		String result = "";
		while(i<source.length() && (Character.isDigit(source.charAt(i)) || source.charAt(i)==' ')) {
			if (source.charAt(i) != ' ')
				result +=source.charAt(i); 
			i++;
		}
		return result;
	}
	
	public static String getCategory(String source) {
		int i = 0;
		while(i<source.length() && (Character.isDigit(source.charAt(i)) || source.charAt(i)==' ')) {
			i++;
		}
		return source.substring(i);
	}
	
	public static int getCategoryId(String[] aCategory, String aText) {
		int count = 0;
		for(String category : aCategory) {
			if (category.trim().equalsIgnoreCase(aText.trim())) {
				return count;
			}
			count++;
		}
		return 0;
	}
	
	public static Double convert(String source) {
		Stack<String> ops  = new Stack<String>();
        Stack<Double> vals = new Stack<Double>();
        String[] elements = convert2Postfix(source).split("(?<=[*/+)(-])|(?=[*/+)(-])");
        for(String element : elements) {
            if      (element.equals("("))               ;
            else if (element.equals("+"))    ops.push(element);
            else if (element.equals("-"))    ops.push(element);
            else if (element.equals("*"))    ops.push(element);
            else if (element.equals("/"))    ops.push(element);
            else if (element.equals("sqrt")) ops.push(element);
            else if (element.equals(")")) {
                String op = ops.pop();
                double v = vals.pop();
                if      (op.equals("+"))    v = vals.pop() + v;
                else if (op.equals("-"))    v = vals.pop() - v;
                else if (op.equals("*"))    v = vals.pop() * v;
                else if (op.equals("/"))    v = vals.pop() / v;
                else if (op.equals("sqrt")) v = Math.sqrt(v);
                vals.push(v);
            }
            else vals.push(Double.parseDouble(element));
        }
        return vals.pop();
	}
	
	private static final String operators = "-+/*";
    private static final String operands = "0123456789";
	
	public static String convert2Postfix(String infixExpr) {
        char[] chars = infixExpr.toCharArray();
        Stack<Character> stack = new Stack<Character>();
        StringBuilder out = new StringBuilder(infixExpr.length());

        for (char c : chars) {
                if (isOperator(c)) {
                        while (!stack.isEmpty() && stack.peek() != '(') {
                                if (operatorGreaterOrEqual(stack.peek(), c)) {
                                        out.append(stack.pop());
                                } else {
                                        break;
                                }
                        }
                        stack.push(c);
                } else if (c == '(') {
                        stack.push(c);
                } else if (c == ')') {
                        while (!stack.isEmpty() && stack.peek() != '(') {
                                out.append(stack.pop());
                        }
                        if (!stack.isEmpty()) {
                                stack.pop();
                        }
                } else if (isOperand(c)) {
                        out.append(c);
                }
        }
        while (!stack.empty()) {
                out.append(stack.pop());
        }
        return out.toString();
	}
	
	private static int getPrecedence(char operator) {
        int ret = 0;
        if (operator == '-' || operator == '+') {
                ret = 1;
        } else if (operator == '*' || operator == '/') {
                ret = 2;
        }
        return ret;
}
private static boolean operatorGreaterOrEqual(char op1, char op2) {
        return getPrecedence(op1) >= getPrecedence(op2);
}

private static boolean isOperator(char val) {
        return operators.indexOf(val) >= 0;
}

private static boolean isOperand(char val) {
        return operands.indexOf(val) >= 0;
}
public static int evalInfix(String infix) {
    return evaluatePostfix(convert2Postfix(infix));
}

public static int evaluatePostfix(String postfixExpr) {
    char[] chars = postfixExpr.toCharArray();
    Stack<Integer> stack = new Stack<Integer>();
    for (char c : chars) {
            if (isOperand(c)) {
                    stack.push(c - '0'); // convert char to int val
            } else if (isOperator(c)) {
                    int op1 = stack.pop();
                    int op2 = stack.pop();
                    int result;
                    switch (c) {
                    case '*':
                            result = op1 * op2;
                            stack.push(result);
                            break;
                    case '/':
                            result = op2 / op1;
                            stack.push(result);
                            break;
                    case '+':
                            result = op1 + op2;
                            stack.push(result);
                            break;
                    case '-':
                            result = op2 - op1;
                            stack.push(result);
                            break;
                    }
            }
    }
    return stack.pop();
}
}
